/*
 * KeyValueVoidKeyImpl_.h
 *
 *  Created on: Aug 3, 2011
 *      Author: yong
 */

#ifndef KEYVALUEVOIDKEYIMPL__H_
#define KEYVALUEVOIDKEYIMPL__H_
#include <stdexcept>
#include <algorithm>
#include <cstring>
#include <utility>
#include <boost/shared_array.hpp>
#include "../Typedef.h"

namespace distrim
{

template<typename V>
class KeyValue<void, V>
{
public:

	typedef V value_type;
	typedef const V const_value_type;

	typedef V* value_pointer;
	typedef V& value_reference;
	typedef const V* const_value_pointer;
	typedef const V& const_value_reference;

	typedef value_pointer value_iterator;
	typedef const_value_pointer const_value_iterator;

	typedef size_t size_type;

	virtual ~KeyValue()
	{
	}
	/**
	 *
	 */
	KeyValue() :
		m_ptrValueBegin(NULL), m_ptrValueEnd(NULL), m_valueElemCount(0)
	{
	}
	/**
	 *
	 */
	KeyValue(size_type valueElemCount) :
		m_ptrValueBegin(NULL), m_ptrValueEnd(NULL), m_valueElemCount(
				valueElemCount)
	{
	}
	/**
	 *
	 */
	KeyValue(value_pointer ptrValueBegin, size_type valueElemCount) :
		m_ptrValueBegin(ptrValueBegin), m_ptrValueEnd(m_ptrValueBegin
				+ m_valueElemCount), m_valueElemCount(valueElemCount)
	{
	}
	/**
	 *
	 */
	KeyValue(value_pointer ptrValueBegin, value_pointer ptrValueEnd) :
		m_ptrValueBegin(ptrValueBegin), m_ptrValueEnd(ptrValueEnd),
				m_valueElemCount(m_ptrValueEnd - m_ptrValueBegin)
	{
	}
	/**
	 *
	 */
	KeyValue(const KeyValue<void, V> &other)
	{
		if (this != &other)
		{
			memcpy(this, &other, sizeof(other));
		}
	}
	/**
	 *
	 */
	const KeyValue& operator=(const KeyValue<void, V> &other)
	{
		if (this != &other)
		{
			BOOST_ASSERT(m_valueElemCount == other.GetValueElemCount());
			memcpy(this, &other, sizeof(*this));
		}
		return *this;
	}

	/**
	 * Clone content from other key-value pair.
	 */
	inline void CloneAll(const KeyValue<void, V> &other)
	{
		CloneValues(other);
	}
	/**
	 *
	 */
	inline void CloneValues(const KeyValue<void, V> &other)
	{
		BOOST_ASSERT(m_valueElemCount == other.GetValueElemCount());
		// Clone values.
		memcpy(begin(), other.begin(), sizeof(V) * m_valueElemCount);
	}
	/**
	 *
	 */
	virtual const KeyValue &operator+(const KeyValue<void, V> &other)
	{
		BOOST_ASSERT(m_valueElemCount == other.GetValueElemCount());
		std::transform(begin(), end(), other.begin(), begin(), std::plus<V>());
		return *this;
	}
	/**
	 * Copy values from an array of values.
	 */
	inline void SetValueElem(const_value_pointer valueElems,
			size_type valueElemCount)
	{
		BOOST_ASSERT(m_valueElemCount == valueElemCount);
		memcpy(begin(), valueElems, sizeof(V) * valueElemCount);
	}
	/**
	 *
	 */
	inline void SetValueBegin(value_pointer ptrValBeg, size_type valueElemCount)
	{
		m_ptrValueBegin = ptrValBeg;
		m_valueElemCount = valueElemCount;
		m_ptrValueEnd = m_ptrValueBegin + m_valueElemCount;
	}
	/**
	 *
	 */
	inline void SetValueBegin(value_pointer ptrValueBegin)
	{
		m_ptrValueBegin = ptrValueBegin;
		m_ptrValueEnd = m_ptrValueBegin + m_valueElemCount;
	}
	/**
	 *
	 */
	inline value_pointer GetValueBegin()
	{
		return m_ptrValueBegin;
	}
	/**
	 *
	 */
	inline const_value_pointer GetValueBegin() const
	{
		return m_ptrValueBegin;
	}
	/**
	 *
	 */
	inline value_pointer GetValueEnd()
	{
		return m_ptrValueEnd;
	}
	/**
	 *
	 */
	inline const_value_pointer GetValueEnd() const
	{
		return m_ptrValueEnd;
	}
	/**
	 *
	 */
	inline size_type GetValueElemCount() const
	{
		return m_valueElemCount;
	}
	/**
	 *
	 */
	inline void SetValueElemCount(size_type valueElemCount)
	{
		m_valueElemCount = valueElemCount;
		m_ptrValueEnd = m_ptrValueBegin + m_valueElemCount;
	}
	/**
	 *
	 */
	inline const_value_type GetValueElem(size_type idx) const
	{
		BOOST_ASSERT(idx >= 0 && idx < m_valueElemCount);
		return operator[](idx);
	}
	/**
	 * Fast value element access support.
	 */
	inline value_reference operator[](size_type idx)
	{
		return m_ptrValueBegin[idx];
	}
	/**
	 *
	 */
	inline const_value_reference operator[](size_type idx) const
	{
		return m_ptrValueBegin[idx];
	}
	/**
	 *
	 */
	inline boost::shared_array<V> GetAllValueElem() const
	{
		return boost::shared_array<V>(new V[m_valueElemCount]);
	}
	/**
	 * Iterator support.
	 */
	inline value_iterator begin()
	{
		return m_ptrValueBegin;
	}
	/**
	 *
	 */
	inline const_value_iterator begin() const
	{
		return m_ptrValueBegin;
	}
	/**
	 *
	 */
	inline value_iterator end()
	{
		return m_ptrValueEnd;
	}
	/**
	 *
	 */
	inline const_value_iterator end() const
	{
		return m_ptrValueEnd;
	}
	/**
	 *
	 */
	inline size_type size() const
	{
		return m_valueElemCount;
	}
	/**
	 *
	 */
	inline bool operator==(const KeyValue<void, V> &other) const
	{
		return true;
	}
	/**
	 *
	 */
	inline bool operator!=(const KeyValue<void, V> &other) const
	{
		return false;
	}

private:

	V* m_ptrValueBegin;

	V* m_ptrValueEnd;

	size_type m_valueElemCount;
};
}

#endif /* KEYVALUEVOIDKEYIMPL__H_ */
